﻿using System;
using System.IO;
using System.Linq;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Sunny.Entity;
using Sunny.Service;
using Sunny.Util.Attributes;

namespace Sunny.Api.Filters
{
    public class OperateFilter : IActionFilter
    {
        private readonly ILogger<OperateFilter> _logger;
        private readonly UserService _userService;
        private readonly IHttpContextAccessor _httpContextAccessor;
        private readonly OperateLogService _operateLogService;

        public OperateFilter(ILogger<OperateFilter> logger, UserService userService,
            IHttpContextAccessor httpContextAccessor, OperateLogService operateLogService)
        {
            _logger = logger;
            _userService = userService;
            _httpContextAccessor = httpContextAccessor;
            _operateLogService = operateLogService;
        }
        

        private object _requestParams;

        public void OnActionExecuting(ActionExecutingContext context)
        {
            this._requestParams = context.ActionArguments.Values.ToList();
            // throw new NotImplementedException();
        }

        public void OnActionExecuted(ActionExecutedContext context)
        {
            var logInfoAttribute = context.ActionDescriptor.EndpointMetadata.FirstOrDefault(t => t.ToString() == typeof(LogInfoAttribute).FullName);
            if (logInfoAttribute is LogInfoAttribute infoAttribute)
            {
                SysOperLog operLog = new SysOperLog();
                var currentUser = _userService.GetCurrentUser();
                var contextActionDescriptor = context.ActionDescriptor;

                operLog.Title = infoAttribute.Title;
                operLog.BusinessType = (int) infoAttribute.BusinessType;
                operLog.OperatorType = (int) infoAttribute.OperatorType;

                operLog.Method = contextActionDescriptor.DisplayName;
                var request = context.HttpContext.Request;

                operLog.RequestMethod = request.Method;

                operLog.OperName = currentUser.UserName;
                operLog.OperUrl = request.Path;
                if (_httpContextAccessor.HttpContext != null)
                    if (_httpContextAccessor.HttpContext.Connection?.RemoteIpAddress != null)
                        operLog.OperIp = _httpContextAccessor.HttpContext.Connection?.RemoteIpAddress.ToString();

                if(this._requestParams !=null)
                {
                    operLog.OperParam =JsonConvert.SerializeObject( this._requestParams);
                }

                if (context.Result is ObjectResult objectResult)
                {
                    operLog.JsonResult = JsonConvert.SerializeObject(objectResult.Value);
                }

                operLog.Status = "0";
                operLog.OperTime = DateTime.Now;

                _operateLogService.Add(operLog);
            }
        }
    }
}